/**
 *
 */
package com.angel.io.parameters;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.angel.common.helpers.StringHelper;
import com.angel.io.exceptions.ParameterNotAddedException;
import com.angel.io.exceptions.ParameterNotFoundException;

/**
 * TODO Verify with Providers. Its functionallity is similar to providers.
 * @author William
 *
 */
public class ParametersService {

	private Map<String, Object> parameters;

	public ParametersService(){
		super();
		this.parameters = new HashMap<String, Object>();
	}

	public void overrideParameter(String name, Object parameter){
		this.checkParameters(name, parameter);

		if(this.containsParameter(name)){
			this.parameters.put(name, parameter);
		} else {
			throw new ParameterNotFoundException("Parameter name [" + name + "] not found to overrided parameter with new paramater [" + parameter.toString() + "].");
		}
	}

	private void checkParameters(String name, Object parameter){
		if(!this.isAValidParameterName(name)){
			throw new ParameterNotAddedException("Parameter name [" + name + "] must NOT be NULL or an empty string.");
		}
		if(!this.isAValidParameterObject(parameter)){
			throw new ParameterNotAddedException("Parameter [" + parameter + "] must NOT be NULL.");
		}
	}

	private boolean isAValidParameterObject(Object parameter){
		return parameter != null && parameter.toString().trim().length() > 0;
	}

	private boolean isAValidParameterName(String name){
		return name != null && name.trim().length() > 0;
	}

	public void addParameter(String name, Object parameter){

		this.checkParameters(name, parameter);

		if(!this.containsParameter(parameter)){
			if(!this.containsParameter(name)){
				this.parameters.put(name, parameter);
			} else {
				throw new ParameterNotAddedException("Parameter name [" + name + "] was found at service asociated with parameter [" + this.findParameter(name).toString() + "]");
			}
		} else {
			throw new ParameterNotAddedException("Parameter [" + parameter .toString()+ "] was found at service asociated with parameter name [" + this.findParameter(name).toString() + "]");
		}
	}

	public Object findParameter(String name){
		if(this.containsParameter(name)){
			return this.parameters.get(name);
		} else {
			throw new ParameterNotFoundException("Parameter [" + name + "] not found at parameters service [" + StringHelper.convertToPlainString(this.parameters.values())+ "].");
		}
	}

	public String findParameter(Object parameter){
		if(this.containsParameter(parameter)){
			Iterator<String> keys = this.parameters.keySet().iterator();
			String key = null;
			boolean found = false;
			while(keys.hasNext()){
				key = keys.next();
				if(!found && this.parameters.get(key).equals(parameter)){
					found = true;
				}
			}
			return key;
		} else {
			throw new ParameterNotFoundException("Parameter object [" + parameter + "] not found at parameters service [" + StringHelper.convertToPlainString(this.parameters.keySet())+ "].");
		}
	}

	public Object removeParameter(String name){
		return this.parameters.remove(name);
	}

	public boolean containsParameter(String name){
		return this.parameters.containsKey(name);
	}

	public boolean containsParameter(Object parameter){
		return this.parameters.containsValue(parameter);
	}

	public Integer quantityParameters(){
		return Integer.valueOf(this.parameters.size());
	}

	public void clearParameters(){
		this.parameters.clear();
	}

}
